package com.fingard.dsp.bank.directbank.alipay01;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayDataDataserviceBillDownloadurlQueryRequest;
import com.alipay.api.request.AlipayFundAccountQueryRequest;
import com.alipay.api.response.AlipayDataDataserviceBillDownloadurlQueryResponse;
import com.alipay.api.response.AlipayFundAccountQueryResponse;
import com.fingard.constant.DateFormat2;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.SendBankRespose;
import com.fingard.dsp.bank.directbank.bankInterface.IBalance;
import com.fingard.dsp.bank.reqrespobj.balance.Req7505HisBalQry;
import com.fingard.dsp.bank.reqrespobj.balance.Req7506BalQry;
import com.fingard.dsp.bank.reqrespobj.balance.RetAts7505HisBalQry;
import com.fingard.dsp.bank.reqrespobj.balance.RetAts7506BalQry;
import com.fingard.dsp.bank.reqrespobj.balance.detail.RetAtsBalDetail;
import com.fingard.dsp.bank.reqrespobj.balance.detail.RetAtsHisBalDetail;
import com.fingard.text.SplitHelper;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import net.sf.json.JSONObject;

import java.io.BufferedReader;
import java.io.File;
import java.io.StringReader;
import java.util.*;

public class ALIPAY01Balance extends ALIPAY01Base implements IBalance {

    /**
     * 当前余额查询
     *
     * @param p_req7506
     * @return
     * @throws Exception
     * @Author Fan
     */
    @Override
    public RetAts7506BalQry d_7506_BalQry(Req7506BalQry p_req7506) throws Exception {

        RetAts7506BalQry retAts = new RetAts7506BalQry(p_req7506.reqHeader);
        RetAtsBalDetail tmpRetDetail = new RetAtsBalDetail();
        retAts.writeStart();
        try {
            while (p_req7506.readRecord()) {
                ActSetItem actItem = getBankConfig().getActSetItemByAny(p_req7506.readedDetail.actNum, "", "", "singlePay");
                if (actItem != null) {
                    DefaultAlipayClient alipayClient = new DefaultAlipayClient(getCertAlipayRequest(actItem));
                    AlipayFundAccountQueryRequest request = new AlipayFundAccountQueryRequest();
                    Map<String, String> paraMap = new HashMap<String, String>();
                    paraMap.put("alipay_user_id", actItem.identity);
                    paraMap.put("account_type", "ACCTRANS_ACCOUNT");
                    String bizContent = JSON.toJSONString(paraMap);
                    request.setBizContent(bizContent);
                    WriteBankLogStep2(bizContent);
                    AlipayFundAccountQueryResponse response = alipayClient.certificateExecute(request);
                    if (response.isSuccess()) {
                        tmpRetDetail.respCode = "0";
                        tmpRetDetail.respInfo = response.getMsg();
                        tmpRetDetail.actArea = p_req7506.readedDetail.actArea;
                        tmpRetDetail.actCur = p_req7506.readedDetail.actCur;
                        tmpRetDetail.actNum = p_req7506.readedDetail.actNum;
                        tmpRetDetail.availBal = response.getAvailableAmount();
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = response.getBody();
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = "未找到账号[" + p_req7506.readedDetail.actNum + "]商户配置信息!";
                }
            }
            retAts.writeRetDetail(tmpRetDetail, p_req7506.isBatch);
        } catch (Exception e) {
            e.printStackTrace();
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(e.getMessage());
            WriteBankLogLn(e);
        }
        retAts.writeEnd();
        return retAts;
    }


    /**
     * 历史余额查询
     *
     * @param p_req7505
     * @return
     * @throws Exception
     */
    @Override
    public RetAts7505HisBalQry d_7505_BalQry(Req7505HisBalQry p_req7505) throws Exception {
        RetAts7505HisBalQry retAts = new RetAts7505HisBalQry(p_req7505.reqHeader);
        retAts.writeStart();
        String tmpRespCode = "";
        String tmpRespInfo = "";
        try {
            logIsExist();

            ActSetItem actItem = getBankConfig().getActSetItem(p_req7505.actNum, "singlePay");
            if (actItem != null) {
                Calendar tmpCalendarFrom = Calendar.getInstance();
                tmpCalendarFrom.setTime(p_req7505.getDateFrom());

                Calendar tmpCalendarTo = Calendar.getInstance();
                tmpCalendarTo.setTime(p_req7505.getDateTo());

                int tmpIntDateFrom = 0;
                int tmpIntDateTo = 0;
                while (tmpIntDateFrom <= tmpIntDateTo && tmpRespCode.length() == 0) {
                    Calendar tmpClndrStepTo = Calendar.getInstance();
                    tmpClndrStepTo.setTime(tmpCalendarFrom.getTime());
                    //判断是否跨月
                    if (DateHelper.compareMonth(tmpCalendarFrom, tmpCalendarTo) == -1) {
                        //跨月则设置为月末
                        tmpClndrStepTo.set(Calendar.DAY_OF_MONTH, tmpClndrStepTo.getActualMaximum(Calendar.DAY_OF_MONTH));
                    } else {
                        tmpClndrStepTo.setTime(tmpCalendarTo.getTime());
                    }

                    // 月内日期段内查询
                    int tmpDateFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
                    int tmpDateTo = Integer.parseInt(Format.Date8Format.format(tmpClndrStepTo.getTime()));
                    while (tmpDateFrom <= tmpDateTo) {
                        AlipayClient alipayClient;
                        if (getBankConfig().getValueAsBool("isPublicKeyAndCert")) {
                            alipayClient = new DefaultAlipayClient(getCertAlipayRequest(actItem));
                        } else {
                            alipayClient = new DefaultAlipayClient(bankFront.serverURL, actItem.appId,
                                    actItem.ownKeyStorePath, "json", getCharset(), actItem.oppCertFilePath, "RSA2");
                        }


                        JSONObject json = new JSONObject();
                        String version = getBankConfig().getValueAsString("version").trim();
                        String billType = getBankConfig().getValueAsString("bill_type").trim();
                        //保险默认使用trade
                        if (StringHelper.isNullOrEmpty(version) || "insurance".equals(version)) {
                            json.put("bill_type", "trade");
                        } else if ("ats".equals(version)) {
                            //ats根据配置决定,默认signcustomer
                            if (StringHelper.isNullOrEmpty(billType)) {
                                billType = "signcustomer";
                            }
                            if (!"trade".equals(billType) && !"signcustomer".equals(billType)) {
                                throw new Exception("bill_type标签配置有误");
                            }
                            json.put("bill_type", billType);

                        } else {
                            throw new Exception("version标签配置有误");
                        }
                        json.put("bill_date", Format.Date10Format.format(tmpCalendarFrom.getTime()));

                        AlipayDataDataserviceBillDownloadurlQueryRequest request = new AlipayDataDataserviceBillDownloadurlQueryRequest();
                        request.setBizContent(JSON.toJSONString(json));

                        WriteBankUrlLogLn(bankFront.serverURL);
                        WriteBankLogStep2(request.getBizContent());

                        AlipayDataDataserviceBillDownloadurlQueryResponse response = null;
                        Boolean useAppAuthToken = getBankConfig().getValueAsBool("useAppAuthToken");
                        if (useAppAuthToken) {
                            if (StringHelper.isNullOrEmpty(actItem.appAuthToken)) {
                                throw new Exception("appAuthToken标签配置有误");
                            }
                            response = alipayClient.execute(request, "", actItem.appAuthToken);
                        } else {
                            response = alipayClient.certificateExecute(request);
                        }

                        WriteBankLogStep3(response.getBody());


                        if ("10000".equals(response.getCode())) {
                            String filePath = createTempFileDirectory() + File.separator + p_req7505.actNum + "_" + tmpDateFrom + ".csv.zip";
                            WriteBankLogLn2("账单下载后保存到本地路径: " + filePath);

                            String billUrl = response.getBillDownloadUrl();
                            WriteBankLogLn2("账单地址获取成功,账单地址链接(30秒有效)为:\r\n" + billUrl);

                            SendBankRespose tmpBankRet = smsGet(billUrl, filePath);
                            WriteBankLogStep3(tmpBankRet);

                            Map<String, String> balMap = new HashMap<String, String>();
                            List<String> dateList = new ArrayList<String>();
                            if (tmpBankRet.connState.length() == 0) {
                                String tmpStrRet = tmpBankRet.retMessage;
                                //保险
                                if (!version.equals("ats")) {
                                    tmpStrRet = tmpStrRet.substring(tmpStrRet.indexOf("支付宝交易号"));
                                    tmpStrRet = tmpStrRet.substring(0, tmpStrRet.indexOf("#"));

                                    StringReader strReader = new StringReader(tmpStrRet);
                                    BufferedReader tmpReader = new BufferedReader(strReader);

                                    String titleLine = tmpReader.readLine();
                                    String[] columns = titleLine.split(",");

                                    while (true) {
                                        String dataLine = tmpReader.readLine();
                                        if (dataLine == null) {
                                            break;
                                        }

                                        String[] values = dataLine.split(",");
                                        if (columns.length == values.length) {
                                            HashMap<String, String> mapKV = SplitHelper.splitAsValueMap(columns, values);
                                            RetAtsHisBalDetail tmpRetDetail = new RetAtsHisBalDetail();

                                            String billDateTime = "";
                                            if (mapKV.containsKey("完成时间")) {
                                                billDateTime = mapKV.get("完成时间").replace("`", "");
                                            }
                                            Date busDateObj = null;
                                            if (billDateTime.contains("-") && billDateTime.length() == 19) {
                                                busDateObj = new DateFormat2("yyyy-MM-dd HH:mm:ss").parse(billDateTime);
                                            } else {
                                                busDateObj = new DateFormat2("yyyy/MM/dd HH:mm").parse(billDateTime);
                                            }
                                            String actBal = Format.DecimalAmtFormat.format(Double.parseDouble(mapKV.get("账户余额（元）").replace("`", "")));
                                            dateList.add(busDateObj.toString());
                                            balMap.put(busDateObj.toString(), actBal);
                                            retAts.writeRetDetail(tmpRetDetail);
                                        } else {
                                            break;
                                        }
                                    }

                                } else if ("trade".equals(billType)) {

                                    tmpStrRet = tmpStrRet.substring(tmpStrRet.indexOf("支付宝交易号"));
                                    tmpStrRet = tmpStrRet.substring(0, tmpStrRet.indexOf("#"));

                                    StringReader strReader = new StringReader(tmpStrRet);
                                    BufferedReader tmpReader = new BufferedReader(strReader);

                                    String titleLine = tmpReader.readLine();
                                    String[] columns = titleLine.split(",", 100);

                                    while (true) {
                                        String dataLine = tmpReader.readLine();
                                        if (dataLine == null) {
                                            break;
                                        }

                                        String[] values = dataLine.split(",", 100);
                                        if (columns.length >= values.length) {
                                            if (columns.length > values.length) {
                                                String[] tmpValues = new String[columns.length];
                                                System.arraycopy(values, 0, tmpValues, 0, values.length);
                                                values = tmpValues;
                                            }
                                            HashMap<String, String> mapKV = SplitHelper.splitAsValueMap(columns, values);
                                            RetAtsHisBalDetail tmpRetDetail = new RetAtsHisBalDetail();

                                            String billDateTime = "";
                                            if (mapKV.containsKey("完成时间")) {
                                                billDateTime = mapKV.get("完成时间").replace("`", "");
                                            }
                                            Date busDateObj = null;
                                            if (billDateTime.contains("-") && billDateTime.length() == 19) {
                                                busDateObj = new DateFormat2("yyyy-MM-dd HH:mm:ss").parse(billDateTime);
                                            } else {
                                                busDateObj = new DateFormat2("yyyy/MM/dd HH:mm").parse(billDateTime);
                                            }
                                            String actBal = Format.DecimalAmtFormat.format(Double.parseDouble(mapKV.get("账户余额（元）").replace("`", "")));
                                            dateList.add(busDateObj.toString());
                                            balMap.put(busDateObj.toString(), actBal);

                                            retAts.writeRetDetail(tmpRetDetail);
                                        } else {
                                            break;
                                        }
                                    }

                                } else {
                                    //账务明细
                                    //账务流水号,业务流水号,商户订单号,商品名称,发生时间,对方账号,收入金额（+元）,支出金额（-元）,账户余额（元）,交易渠道,业务类型,备注
                                    tmpStrRet = tmpStrRet.substring(tmpStrRet.indexOf("账务流水号"));
//									tmpStrRet = tmpStrRet.substring(0, tmpStrRet.indexOf("#"));

                                    StringReader strReader = new StringReader(tmpStrRet);
                                    BufferedReader tmpReader = new BufferedReader(strReader);

                                    String titleLine = tmpReader.readLine();
                                    String[] columns = titleLine.split(",");
                                    RetAtsHisBalDetail tmpRetDetail = new RetAtsHisBalDetail();

                                    while (true) {
                                        String dataLine = tmpReader.readLine();
                                        if (dataLine == null) {
                                            break;
                                        }

                                        String[] values = dataLine.split(",");
                                        if (columns.length == values.length) {
                                            if (columns.length > values.length) {
                                                String[] tmpValues = new String[columns.length];
                                                System.arraycopy(values, 0, tmpValues, 0, values.length);
                                                values = tmpValues;
                                            }
                                            HashMap<String, String> mapKV = SplitHelper.splitAsValueMap(columns, values);

                                            String billDateTime = "";
                                            if (mapKV.containsKey("发生时间")) {
                                                billDateTime = mapKV.get("发生时间").trim();
                                                ;
                                            }
                                            Date busDateObj = null;
                                            if (billDateTime.contains("-") && billDateTime.length() == 19) {
                                                busDateObj = new DateFormat2("yyyy-MM-dd HH:mm:ss").parse(billDateTime);
                                            } else {
                                                busDateObj = new DateFormat2("yyyy/MM/dd HH:mm").parse(billDateTime);
                                            }
                                            String actBal = Format.DecimalAmtFormat.format(Double.parseDouble(mapKV.get("账户余额（元）").trim()));
                                            dateList.add(busDateObj.toString());
                                            balMap.put(busDateObj.toString(), actBal);
                                        } else {
                                            break;
                                        }
                                    }
                                    if (balMap.get(Collections.max(dateList)) != null) {
                                        tmpRetDetail.availBal = balMap.get(Collections.max(dateList));
                                    }
                                    tmpRetDetail.balDate = Format.Date8Format.format(tmpCalendarFrom.getTime());
                                    retAts.writeRetDetail(tmpRetDetail);
                                }
                            } else {
                                tmpRespCode = "-1";
                                tmpRespInfo = tmpBankRet.retMessage;
                            }
                        } else if ("40004".equals(response.getCode())) {
//                      当天没有交易
                        } else {
                            tmpRespCode = "-1";
                            tmpRespInfo = response.getSubMsg();
                        }
                        tmpCalendarFrom.add(Calendar.DAY_OF_MONTH, 1);
                        tmpDateFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
                    }

                    tmpCalendarFrom = tmpClndrStepTo;
                    tmpCalendarFrom.add(Calendar.DAY_OF_MONTH, 1);
                    tmpIntDateFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
                    tmpIntDateTo = Integer.parseInt(Format.Date8Format.format(tmpCalendarTo.getTime()));
                }
            } else {
                tmpRespCode = "-1";
                tmpRespInfo = "未找到账号[" + p_req7505.actNum + "]商户配置信息!";
            }
        } catch (Exception e) {
            tmpRespCode = "-1";
            tmpRespInfo = e.getMessage();
            WriteBankLogLn(e);
            e.printStackTrace();
        }
        if (tmpRespCode.equals("-1")) {
            retAts = new RetAts7505HisBalQry(p_req7505.reqHeader);
            retAts.writeStart();//写返回ATS的统一头部信息
            retAts.writeRespCode(tmpRespCode);
            retAts.writeRespInfo(tmpRespInfo);
        } else if (retAts.getWrittenRdCount() == 0) {
            retAts.writeRespCode("0");
            retAts.writeRespInfo("交易为空");
        }
        retAts.writeEnd();
        return retAts;
    }
}
